package export

import (
	"github.com/lab-online/internal/report/entity"
	"github.com/lab-online/internal/report/interface/export"
	"github.com/lab-online/internal/shared/valueobject"
	"github.com/lab-online/pkg/util"
)

type Repository interface {
	GetReportByID(id uint) (entity.ReportEntity, error)
	SaveReport(entity.ReportEntity) (entity.ReportEntity, error)
	SearchReport(entity.ReportEntity) ([]entity.ReportEntity, error)
	GetReportByStudentAndClassIDAndExperimentID(
		student string, classID, experimentID uint,
	) (entity.ReportEntity, error)
}

type exportService struct {
	repository Repository
}

func New(repository Repository) export.ReportService {
	return &exportService{repository}
}

func (e *exportService) SaveReport(report *valueobject.Report) (valueobject.ReportVO, error) {
	if reportEntity, err := e.repository.SaveReport(voTOEntityMapper(report)); err != nil {
		return nil, err
	} else {
		return reportEntity, nil
	}
}

func (e *exportService) GetReportByID(id uint) (valueobject.ReportVO, error) {
	if report, err := e.repository.GetReportByID(id); err != nil {
		return nil, err
	} else {
		return report, nil
	}
}

func (e *exportService) SearchReport(report *valueobject.Report) ([]valueobject.ReportVO, error) {
	if reports, err := e.repository.SearchReport(voTOEntityMapper(report)); err != nil {
		return nil, err
	} else {
		return util.SliceMap(reports, entityToVOMapper), nil
	}
}

func (e *exportService) GetReportByStudentAndClassIDAndExperimentID(
	student string, classID, experimentID uint,
) (valueobject.ReportVO, error) {
	return e.repository.GetReportByStudentAndClassIDAndExperimentID(student, classID, experimentID)
}

func (e *exportService) GetReportByExperimentID(
	experimentID uint,
) ([]valueobject.ReportVO, error) {
	// TODO: Implement this method
	return nil, nil
}
